package at.sysarch.filter;

import java.awt.Point;
import java.awt.image.Raster;
import java.util.ArrayList;
import java.util.List;

import at.pimpmypipe.filter.DataEnrichmentFilter;
import at.sysarch.domain.Centroids;
import at.sysarch.domain.TransferImage;

public class CentroidFilter extends DataEnrichmentFilter<TransferImage, Centroids> {
	
	private static final int WHITE = 255;
	
	private List<Point> _templatePoints;
	private int _xTolerance;
	private int _yTolerance;

	@Override
	protected boolean fillEntity(TransferImage nextVal, Centroids entity) {

		Raster imageRaster = nextVal.getModifiedImage().getData();
		double[] pixel = new double[3];
		boolean diskEntered = false;
		boolean diskLeft = true;
		List<Point> diskPixels = null;
		List<Point> centroids = new ArrayList<Point>();
		
		for (int i = 0; i < imageRaster.getWidth(); i++) {
			diskLeft = true;
			for (int j = 0; j < imageRaster.getHeight(); j++) {
				
				imageRaster.getPixel(i, j, pixel);
				
				if (pixel[0] == WHITE && pixel[1] == WHITE && pixel[2] == WHITE) {
					
					if (!diskEntered) {
						
						diskPixels = new ArrayList<Point>();
						diskEntered = true;
					}
					if (diskEntered) {
						
						diskPixels.add(new Point(i, j));
						diskLeft = false;
					}
				}
			}
			
			if (diskLeft == true) {
				
				diskEntered = false;
				if (diskPixels != null) {
					Point centroid = new Point();
					
					int sumX = 0;
					int sumY = 0;
					
					for (Point p: diskPixels) {
						
						sumX += p.x;
						sumY += p.y;
					}
					
					centroid.x = sumX / diskPixels.size();
					centroid.y = sumY / diskPixels.size();
					
					centroids.add(centroid);
					
					diskPixels = null;
				}
			}
		}
		
		for (int i = 0; i < centroids.size(); i++) {
			
			boolean inTolerance = isInTolerance(centroids.get(i), _templatePoints.get(i));
			
			entity.addCentroid(centroids.get(i), _templatePoints.get(i), inTolerance);
		}

		return true;
	}

	@Override
	protected Centroids getNewEntityObject() {

		return new Centroids();
	}
	
	private boolean isInTolerance(Point centroid, Point templatePoint) {
		
		if (Math.abs(centroid.x - templatePoint.x) < _xTolerance
			&& Math.abs(centroid.y - templatePoint.y) < _yTolerance) {
			
			return true;
		} else {
			
			return false;
		}
	}

	public void setTemplatePoints(List<Point> templatePoints) {
		_templatePoints = templatePoints;
	}

	public void setTolerance(int xTolerance, int yTolerance) {
		_xTolerance = xTolerance;
		_yTolerance = yTolerance;
	}
}
